<?php


namespace Tbf\Bundle\AlipayBundle\Model;


class AlipaySign {
    /**
     * 使用md5方式签名数组,返回签名后的数组
     * @param array $data map[string]string
     * @param
     * @return array $data map[string]string
     */
    static public function md5SignArray(array $data,$key){
        //除去待签名参数数组中的空值和签名参数
        $data = self::paraFilter($data);

        //对待签名参数数组排序
        $data = self::argSort($data);

        //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = self::createLinkstring($data);

        $mysign = self::md5SignString($prestr, $key);

        //签名结果与签名方式加入请求提交参数组中
        $data['sign'] = $mysign;
        $data['sign_type'] = 'MD5';
        return $data;
    }
    /**
     * 使用md5方式验证输入数组签名
     * @param array $data map[string]string
     * @return boolean
     */
    static public function md5SignVerifyArray($data,$key){
        if (empty($data['sign'])){
            return false;
        }
        $sign = $data['sign'];
        //除去待签名参数数组中的空值和签名参数
        $para_filter = self::paraFilter($data);

        //对待签名参数数组排序
        $para_sort = self::argSort($para_filter);
        //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = self::createLinkstring($para_sort);

        return self::md5Verify($prestr, $sign, $key);
    }

    /**
     * 除去数组中的空值和签名参数
     * @param array $para 签名参数组
     * @return array去掉空值与签名参数后的新签名参数组
     */
    protected  static function paraFilter($para)
    {
        unset($para['sign']);
        unset($para['sign_type']);
        foreach($para as $key=>$value){
            if (empty($value)){
                unset($para[$key]);
            }
        }
        return $para;
    }
    /**
     * 对数组排序
     * @param $para 排序前的数组
     * return 排序后的数组
     */
    protected static function argSort($para)
    {
        ksort($para);
        reset($para);

        return $para;
    }
    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para 需要拼接的数组
     * return 拼接完成以后的字符串
     */
    protected static function createLinkstring($para)
    {
        $arg  = "";
        while (list ($key, $val) = each ($para)) {
            $arg.=$key."=".$val."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg,0,count($arg)-2);

        //如果存在转义字符，那么去掉转义
        if (get_magic_quotes_gpc()) {$arg = stripslashes($arg);}

        return $arg;
    }
    /**
     * 签名字符串
     * @param $prestr 需要签名的字符串
     * @param $key 私钥
     * return 签名结果
     */
    protected static function md5SignString($prestr, $key)
    {
        $prestr = $prestr . $key;

        return md5($prestr);
    }
    /**
     * 验证签名
     * @param $prestr 需要签名的字符串
     * @param $sign 签名结果
     * @param $key 私钥
     * return 签名结果
     */
    protected  static function md5Verify($prestr, $sign, $key)
    {
        $prestr = $prestr . $key;
        $mysgin = md5($prestr);

        if ($mysgin == $sign) {
            return true;
        } else {
            return false;
        }
    }
}